<template>
  <div>
    <div v-if="isSqlSearch" class="sql-search-view">
      <div class="sql-return-bar">
        <a-button class="cancel-button" type="link" icon="left" @click="cancel">
          <span>返回</span>
        </a-button>
        <span class="sql-text" style="color: #999;">| </span>
        <span class="sql-text"> SQL查询</span>
      </div>
      <div class="upload-content content">
        <sql-search-page />
      </div>
    </div>
    <div v-else class="data-management">
      <a-tabs
        v-model="dataTabIndex"
        class="data-management-content"
        default-active-key="1"
        @change="changeTab"
      >
        <a-tab-pane key="1" tab="我的数据">
          <a-tooltip class="hover-tip">
            <template slot="title">
              选中文件后可直接拖动更改分类
            </template>
            ?
          </a-tooltip>
          <!-- <div class="hover-tip">?</div> -->
          <a-layout>
            <a-layout-sider width="220px">
              <data-sider
                ref="dataSider"
                :selected-keys="selectedKeys"
                @set-selected-keys="setSelectedKeys"
              ></data-sider>
            </a-layout-sider>
            <a-layout-content ref="dataview">
              <div class="dataview-contentwrapper">
                <div
                  v-if="
                    selectedDatasetId < 0 &&
                    !selectedGraphFileName &&
                    !isUploading &&
                    !isSqlSearch
                  "
                  class="dataview-empty"
                >
                  <div>
                    <img alt="" src="@/assets/view/dataview-empty.svg" />
                    <div>暂无详情</div>
                    <div>请先创建分类导入数据~</div>
                  </div>
                </div>
                <div v-else class="dataview-content">
                  <div v-if="isUploading" class="return-bar">
                    <a-button
                      class="cancel-button"
                      type="link"
                      icon="close"
                      @click="cancel"
                    >
                      <span>取消</span>
                    </a-button>
                    <span class="upload-text" style="color: #999;">| </span>
                    <span class="upload-text"> 导入数据</span>
                  </div>
                  <div v-if="dataIsUploading">
                    <data-is-uploaded-page
                      class="upload-progress-container"
                      :upload-progresses="getResult"
                      :finished="finished"
                      @reset-result="resetResult"
                      @set-selected-keys="setSelectedKeys"
                      @clear-progresses-interval="clearProgressesInterval"
                    />
                  </div>
                  <div v-if="isUploading" class="upload-content content">
                    <div
                      v-if="dataIsUploading"
                      :class="{ 'upload-mask': !uploadFinished }"
                    />
                    <data-upload-page
                      id="data-upload-page"
                      ref="dataUploadPage"
                      :style="{
                        opacity: dataIsUploading && !uploadFinished ? 0.6 : 1,
                      }"
                      @begin-database-upload="beginDatabaseDataUpload"
                      @set-selected-keys="setSelectedKeys"
                    />
                  </div>
                  <div v-else class="content">
                    <data-view-content
                      v-if="selectedDatasetId >= 0 || selectedGraphFileName"
                      :is-in-sql="false"
                    />
                  </div>
                </div>
              </div>
            </a-layout-content>
          </a-layout>
        </a-tab-pane>
        <a-tab-pane key="2" tab="数据统计">
          <data-status-page />
        </a-tab-pane>
      </a-tabs>
      <DataEditModal :selected-database-type="'mysql'"></DataEditModal>
    </div>
    <!-- 开始引导弹框 -->
    <guide-start-end-modal :type="'start'" />
  </div>
</template>

<script lang="ts">
/**
 * data management view
 * @author Huihua Lu
 */
import { Component, Vue, Watch } from 'vue-property-decorator'
// @ts-ignored
import AProgress from 'ant-design-vue/es/progress/progress'
import DataSider from '@/components/data/DataSider.vue'
import DataViewContent from '@/components/data/DataViewContent.vue'
import DataStore from '@/store/modules/data'
import DataUploadPage from '@/components/data/DataUploadPage.vue'
import DataIsUploadedPage from '@/components/data/DataIsUploadedPage.vue'
import SqlSearchPage from '@/components/data/SqlSearchPage.vue'
import { Modal } from 'ant-design-vue'
import {
  setWatermark,
  deleteWatermark,
  removeResizeListener,
} from '@/util/util'
import UserStore from '@/store/modules/user'
import DataStatusPage from '@/components/data/DataStatusPage.vue'
import DataEditModal from '@/components/data/DatasetEditModal.vue'
import GuideStartEndModal from '@/components/user-guide/GuideStartEndModal.vue'

@Component({
  components: {
    DataSider,
    DataViewContent,
    DataUploadPage,
    DataIsUploadedPage,
    AProgress,
    SqlSearchPage,
    DataStatusPage,
    DataEditModal,
    GuideStartEndModal,
  },
})
export default class DataView extends Vue {
  // 轮询timer
  private timer: any
  // 轮询得到的任务进度
  public result: any = { finalFlag: false, progress: [] }
  // 任务是否已完成
  private finished: boolean = false
  // 侧边栏选中的项目
  private selectedKeys = ['']

  private dataTabIndex: string = '1'

  public $refs!: {
    dataSider: any
    dataview: any
    dataUploadPage: DataUploadPage
  }

  async created() {
    this.enableTaskPolling()
    this.dataTabIndex = DataStore.dataTabIndex

    // this.getTaskProgresses()
  }

  public mounted() {
    if (this.$route.path === '/management/data/import') {
      DataStore.setIsUploading(true)
    } else {
      DataStore.setIsUploading(false)
    }
  }
  //  创建水印的函数
  private createWaterMark() {
    const areaName = '.dataview-contentwrapper'
    setTimeout(() => {
      setWatermark(this.username, areaName)
    }, 500)
  }

  public get username() {
    return UserStore.currentUser ? UserStore.currentUser.name : '未命名用户'
  }
  beforeDestroy() {
    deleteWatermark('water_mark')
    removeResizeListener()
  }

  destroyed() {
    clearInterval(this.timer)
    DataStore.cancelImport()
  }

  public get currentTabIndex() {
    return DataStore.dataTabIndex
  }

  @Watch('currentTabIndex', { immediate: true, deep: true })
  onCurrentTabIndexChanged() {
    this.dataTabIndex = DataStore.dataTabIndex
  }

  public get routePath() {
    return this.$route.path
  }
  @Watch('routePath', { immediate: true, deep: true })
  onPathChanged() {
    console.log('path change')
    if (this.$route.path === '/management/data') {
      DataStore.setDataTabIndex('1')
      //  若不存在水印，则需要创建
      if (!document.querySelector('#water_mark')) {
        this.createWaterMark()
      }
    } else if (this.$route.path === '/management/data/status') {
      DataStore.setDataTabIndex('2')
    }
  }

  @Watch('isUploading')
  onIsUploadingChange() {
    if (!this.isUploading && this.routePath === '/management/data/import') {
      this.$router.replace('/management/data')
    }
  }

  public changeTab(key: any) {
    DataStore.setDataTabIndex(key)
    if (key === '2') {
      this.$router.push('/management/data/status')
    } else {
      this.$router.push('/management/data')
    }
    this.dataTabIndex = DataStore.dataTabIndex
  }

  private uploadFinished = false

  // 上传页面发起上传请求，开始轮询
  public async beginDatabaseDataUpload(passData: any) {
    this.resetResult()
    this.uploadFinished = false
    // 标识当前开始导入
    DataStore.setBeginDatabaseUpload(true)
    // 显示加载进度页面
    DataStore.setDataIsUploading(true)
    await DataStore.uploadDatabase(passData).then(() => {
      this.enableTaskPolling()
    })
    // TODO
    this.$refs.dataUploadPage.updateDataSuccessToGuideStep(5)
  }

  // 开启任务状态轮询
  public async enableTaskPolling() {
    await this.getTaskProgresses()
    // 任务未完成，当前正在导入数据，则轮询查看当前任务是否上传完毕
    if (this.result && !this.result.finalFlag) {
      this.timer = setInterval(async () => {
        await this.getTaskProgresses()
      }, 2000)
    }
  }

  public async getTaskProgresses() {
    await DataStore.getDatabaseImportProgress()
      .then(async (response) => {
        if (response.status !== 200 && response.data.code !== 100) {
          this.$message.error(
            `进度信息获取失败！错误信息：${response.data.message}`
          )
          this.finished = true
          clearInterval(this.timer)
        }
        if (!this.finished) {
          this.result = response.data.result
        }
        if (!this.result) {
          if (this.beginDatabaseUpload) {
            // 数据导入页面点击确定跳转过来的逻辑，忽略result=null的状态，可能后端还未修改
            this.finished = false
            DataStore.setBeginDatabaseUpload(false)
          } else {
            // 页面初始化时的逻辑，result===null，则停止轮询
            DataStore.loadDatasetCategory()
            DataStore.setDataIsUploading(false)
            this.finished = true
          }
        } else {
          DataStore.setDataIsUploading(true)
          this.result = response.data.result
          if (this.result.finalFlag) {
            this.uploadFinished = true
            // 任务已完成或已取消
            await DataStore.loadDatasetCategory()
            this.finished = true
            let isHealthy = true
            console.log(this.result, '--------------')
            this.result.progresses.forEach((item: any) => {
              if (item.err) {
                isHealthy = false
              }
            })
            if (isHealthy) {
              this.$message.success('数据上传导入完成！')
              const datasetIds = this.result.progresses.map((value: any) => {
                return value.datasetId
              })
              const lastTableId = datasetIds.slice(-1)[0]
              DataStore.setSelectedDatasetId(lastTableId)
              console.log(`dataset${lastTableId}`, '--------')
              this.setSelectedKeys([`dataset${lastTableId}`])
              DataStore.cancelImport()
              DataStore.setDataIsUploading(true)
              this.$router.push('/management/data')
            } else {
              this.$message.error('部分数据导入失败！')
            }
          } else {
            // 任务未完成
            this.result = response.data.result
            this.finished = false
          }
          if (this.finished) {
            clearInterval(this.timer)
            DataStore.loadDatasetCategory()
          }
        }
      })
      .catch(() => {
        this.$message.error('任务进度获取失败')
        clearInterval(this.timer)
      })
  }

  // 重置进度
  public resetResult() {
    // if(!this.result)
    this.result = { finalFlag: false, progresses: [] }
    // console.log('reset---befor-----',this.result)
    // this.result.finalFlag=false
    // this.result.progresses=[]
    DataStore.setDataIsUploading(false)
    console.log('reset---after-----', this.result)
  }

  public get selectedDatasetId() {
    return DataStore.selectedDatasetId
  }

  public get selectedGraphFileName() {
    return DataStore.selectedGraphFileName
  }

  public get isUploading() {
    return DataStore.isUploading
  }

  public get dataIsUploading() {
    return DataStore.dataIsUploading
    // return true
  }

  public get beginDatabaseUpload() {
    return DataStore.beginDatabaseUpload
  }

  public get getResult() {
    if (!this.result) {
      this.result = { progresses: [], finalFlag: false }
    }
    let sumCostTime = 0
    let sumCount = 0
    // this.result = {finalFlag:true, progresses:[{table: 'aa23a',progress:12,err:'1111111'},{table:'aaab',progress:10000,costTime:123,count:1000},{table:'aaa',progress:780,count:1000},{table:'bbb',progress:1235,status:'进行中'},{table:'bbb2',progress:1235,status:'进行中'}]}
    if (this.result.finalFlag) {
      this.result.progresses.forEach((item: any) => {
        if (item.progress === 10000 && !item.err) {
          sumCostTime =
            item.costTime > sumCostTime ? item.costTime : sumCostTime
          sumCount += item.count
        }
      })
      this.$set(this.result, 'sumCostTime', sumCostTime)
      this.$set(this.result, 'sumCount', sumCount)
    }
    return this.result
  }

  // 停止轮询查看导入进度
  public clearProgressesInterval() {
    clearInterval(this.timer)
    // 获取最终进度结果
    DataStore.getDatabaseImportProgress().then((response) => {
      if (response.data.code === 100) {
        this.result = response.data.result
      } else {
        this.$message.error('进度获取失败')
      }
    })
  }

  // // 点击“导入数据按钮”之后的交互
  // public clickUploadButton() {
  //   // 已经传输完毕，则隐藏进度页面
  //   if(this.finished) {
  //     DataStore.cancelImport()
  //     DataStore.setIsUploading(true)
  //     if(!this.result)
  //     DataStore.setDataIsUploading(false)
  //   }
  // }

  public get lastOfPreSelectedDataset() {
    return DataStore.preSelectedDataset.length > 0
      ? DataStore.preSelectedDataset.slice(-1)[0]
      : { id: -1, name: '', type: '' }
  }

  // 取消按钮逻辑
  public cancel() {
    if (
      DataStore.isUploading &&
      DataStore.dataIsUploading &&
      !this.uploadFinished
    ) {
      // 当前为数据进度展示页面，点击取消->取消未完成任务
      Modal.confirm({
        title: '确定要取消数据导入么？',
        content: '取消数据导入将取消所有未完成的任务',
        okText: '确定',
        cancelText: '取消',
        onOk: this.cancelDatabaseImport,
      })
    } else if (DataStore.isUploading) {
      // 导入界面，返回之前的数据表视图
      DataStore.setIsUploading(false)
      DataStore.setSelectedDatasetId(this.lastOfPreSelectedDataset.id)
      this.$router.push('/management/data')
    } else {
      // 数据表页面，返回之前查看的数据表视图
      DataStore.setSelectedDatasetId(this.lastOfPreSelectedDataset.id)
      this.selectedKeys = [this.lastOfPreSelectedDataset.name]
      DataStore.popPreSelectedDataset()
      this.$router.push('/management/data')
    }
  }

  // 取消导入
  public async cancelDatabaseImport() {
    await DataStore.cancelDatabaseImport().then((response) => {
      if (response.data.code === 100) {
        // 停止轮询
        this.clearProgressesInterval()
        this.$message.success('未完成任务取消成功')
      } else if (response.data.code === 40010) {
        // 任务实际已经传输成功，提示相应结果
        this.$message.config({ maxCount: 2 })
        this.$message.warn('数据导入已结束，取消失败')
      } else {
        this.$message.error('任务取消失败', response.data.message)
      }
    })
    // 清除导入的数据状态
    this.$refs.dataUploadPage.clearImportStatus()
    this.uploadFinished = true
  }

  // 设置侧边栏选中的项目
  public setSelectedKeys(keys: any) {
    this.selectedKeys = keys
    let selectedCategory = ''
    DataStore.datasetCategory.forEach((category) => {
      category.dataset.forEach((dataset) => {
        if (keys[0].includes(dataset.id)) {
          selectedCategory = `category${category.categoryId}`
        }
      })
    })
    if (
      !selectedCategory &&
      DataStore.graphFileList.includes(keys[0].replace('graph-', ''))
    ) {
      // 再找图文件数据集
      DataStore.setSelectedGraphFileName(keys[0].replace('graph-', ''))
      selectedCategory = 'category0' // ToDo 优化
    }
    const expandedCategoris = [selectedCategory]
    // const expandedCategoris = [...this.$refs.dataSider.expandedKeys,selectedCategory]
    if (!this.$refs.dataSider.expandedKeys.includes(selectedCategory)) {
      this.$set(this.$refs.dataSider, 'expandedKeys', expandedCategoris)
    }
  }

  // sql查询
  public get isSqlSearch() {
    if (this.$route.path === '/management/data/sqlSearch') {
      DataStore.setIsSqlSearch(true)
    } else {
      DataStore.setIsSqlSearch(false)
    }
    console.log(DataStore.isSqlSearch)
    return DataStore.isSqlSearch
  }
}
</script>

<style lang="less" scoped>
@import '@/constants';

.data-management {
  background: #fff;
  margin: 16px;
  max-height: calc(100vh - 140px);
  min-height: calc(100vh - 140px);
  padding-left: 24px;
  padding-right: 0;
}

.hover-tip {
  background-color: #6973ff;
  border-radius: 50%;
  color: #fff;
  cursor: pointer;
  font-size: 12px;
  height: 16px;
  left: 80px;
  padding-left: 4px;
  position: absolute;
  top: 4px;
  width: 16px;
  z-index: 100;
}

.sql-search-view {
  background: #f3f3f3;
  margin: 16px;
  max-height: calc(100vh - 140px);
  min-height: calc(100vh - 140px);
}

.ant-layout {
  background: #fff;
  bottom: 0;
  height: 100%;
  max-height: calc(100vh - 208px);
  min-height: calc(100vh - 208px);
  overflow-y: hidden;
  width: 100%;
}

.sql-text {
  color: #373b52;
  font-size: 16px;
  font-weight: 500;
  letter-spacing: 1px;
  line-height: 22px;
}

.ant-layout-sider {
  background-color: #fff;
  border-right: 1px solid#E9E9E9;
  bottom: 0;
  height: 100%;
  left: -24px;
  top: 0;
}

.ant-layout-content {
  bottom: 0;
  height: 100%;
  left: 220px;
  margin-left: -24px;
  right: 0;
  top: 0;
}

// 数据导入部分
.dataview-contentwrapper {
  background-color: #f3f3f7;
  height: 100%;
  padding: 11px 0 0 15px;
  position: relative;
  width: 100%;
}

// 空状态div
.dataview-empty {
  align-items: center;
  background-color: #fff;
  display: flex;
  height: 100%;
  justify-content: center;
  text-align: center;
}

// 数据管理页面内容
.dataview-content {
  align-items: center;
  background-color: #fff;
  height: 100%;
  justify-content: center;
  width: 100%;
}

// 返回栏
.return-bar {
  background-color: #fff;
  border-bottom: 1px solid #f3f3f7;
  height: 54px;
}

.sql-return-bar {
  background-color: #fff;
  height: 54px;
  margin-bottom: 11px;
}

// 取消按钮
.cancel-button {
  color: #6973ff;
  font-size: 16px;
  height: 100%;
  letter-spacing: 1px;
}

// 文字-“导入数据”
.upload-text {
  color: #373b52;
  font-size: 16px;
  height: 100%;
  letter-spacing: 1px;
}

// 内容部分
.content {
  background-color: #fff;
  height: 100%;
  overflow-y: auto;
  width: 100%;

  &::-webkit-scrollbar {
    height: 6px;
    width: 6px;
  }

  &::-webkit-scrollbar-thumb {
    background: rgba(144, 147, 153, 0.5);
    border-radius: 6px;
  }

  &::-webkit-scrollbar-track {
    background: transparent;
    border-radius: 5px;
  }
}

// 导入部分
.upload-content {
  background-color: #fff;
  height: calc(100% - 66px);
  overflow-y: auto;
  width: 100%;
}

// 上传过程中覆盖的蒙层
.upload-mask {
  height: 100%;
  position: fixed;
  width: 100%;
  z-index: 999;
}

// 导入进度部分
.upload-progress-container {
  background-color: #fff;
  border: 1px solid #e9e9e9;
  border-radius: 4px;
  max-height: 168px;
  position: fixed;
  width: 366px;
  z-index: 1000;
}

// sql查询
.sql-search-content {
  background-color: #fff;
  height: calc(100% - 66px);
  left: 0;
  overflow-y: auto;
  position: absolute;
  right: 0;
}

.dataview-sql {
  align-items: center;
  background-color: #fff;
  display: flex;
  height: 100%;
  justify-content: center;
  text-align: center;
}
</style>
